
class HashTags

    HASHTAG_TABLE     = "hashtags"
    HASHTAG_TABLE_ID  = "id"
    HASHTAG_TABLE_TAG = "tag"

    #Creates a HashTags object that allows accessing
    #the HashTags database.
    def initialize(mysql_con)
        @hashtags         = Array.new
        @mysql_connection = mysql_con 
    end
    
    #Loads the hashtags from the database.
    def load()
        @hashtags.clear()
        results = @mysql_connection.query("SELECT * FROM #{HASHTAG_TABLE}")
        results.each_hash do |row|
            @hashtags.push(HashTag.new(row[HASHTAG_TABLE_TAG], 
                                       row[HASHTAG_TABLE_ID]))
        end
    end
    
    #Save the hashtags to the database.
    def save()

        #Add new hashtags to the database.
        query_string                          = "INSERT INTO #{HASHTAG_TABLE} (#{HASHTAG_TABLE_TAG}) VALUES "
        new_tags                              = @hashtags.select{ |ht| ht.state == :added };
        if (!new_tags.empty?)
            new_tags.each{ |ht| query_string  += " ( '#{ht.tag}' )," }
            query_string                      = query_string[0..-2] + ";"
            @mysql_connection.query(query_string)
        end

        #Delete removed hashtags from the database.
        query_string = "DELETE FROM #{HASHTAG_TABLE} WHERE #{HASHTAG_TABLE_ID} IN (";
        remove_tags  = @hashtags.select{ |ht| ht.state == :removed }
        if (!remove_tags.empty?) 
            remove_tags.each { |ht| query_string += " #{ht.id}," }
            query_string                     = query_string[0..-2] + " );"
            @mysql_connection.query(query_string);
        end
    end

    #Returns a cloned array of hashtags.
    def get_hashtags()
        return @hashtags.clone()
    end

    #Adds a hashtag. Note that this doesn't actually add it
    #to the database until the save method is called.
    def add_hashtag(hashtag)
        if (@hashtags.count{ |ht| ht.tag == hashtag } == 0)
            @hashtags.push(HashTag.new(hashtag, HashTag::NULL_ID, :added))
        end
    end

    #Removes a hashtag. Note that this doesn't actually remove it
    #from the database until the save method is called.
    #This method actually just changes the state.
    def remove_hashtag(hashtag)
	remove_tags = @hashtags.select { |ht| ht.tag == hashtag }
        if (!remove_tags.empty?)
            id = remove_tags.first().id
            @hashtags.delete_if { |ht| ht.tag == hashtag }
            @hashtags.push(HashTag.new(hashtag, id, :removed))
        end
    end

end

#A simple HashTag class for storing information about a hashtag.
class HashTag

    #This is the id of a hashtag which has not been loaded from the database.
    NULL_ID = -1

    #@tag is the actual text of the hashtag.
    #@id is the underlying id in the mysql database. It may also be NULL_ID if it
    #has not yet been loaded from the database.
    #@state is the state of the hash tag.
    #The valid states are:
    # :loaded which means the tag was loaded from the database.
    # :added which means the tag was added but has not been saved to the database.
    # :removed which means the tag was removed but not yet deleted from the database.
    attr_reader :tag, :id, :state
    
    #Just creates a hashtag with the relevent information.
    def initialize(hashtag, hashtag_id, hashtag_state = :loaded)
        @tag, @id = hashtag, hashtag_id
        @state    = hashtag_state
    end
end
